package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.common.dto.PageResponseResult;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.util.WeMediaThreadLocal;
import com.heima.wemedia.dto.ContentDto;
import com.heima.wemedia.dto.NewsAuthDto;
import com.heima.wemedia.dto.WmNewsDto;
import com.heima.wemedia.dto.WmNewsPageDto;
import com.heima.wemedia.entity.WmMaterial;
import com.heima.wemedia.entity.WmNews;
import com.heima.wemedia.entity.WmNewsMaterial;
import com.heima.wemedia.entity.WmUser;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.service.IWmMaterialService;
import com.heima.wemedia.service.IWmNewsMaterialService;
import com.heima.wemedia.service.IWmNewsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.wemedia.service.IWmUserService;
import com.heima.wemedia.vo.WmNewsVo;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 自媒体图文内容信息表 服务实现类
 * </p>
 *
 * @author mcm
 * @since 2021-05-22
 */
@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements IWmNewsService {
    @Value("${topic.autoAuditTopic}")
    private String autoAuditTopic;

    @Value("${topic.upDownTopic}")
    private String upDownTopic;

    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    @Autowired
    private IWmMaterialService iWmMaterialService;

    @Autowired
    private IWmNewsMaterialService iWmNewsMaterialService;

    @Autowired
    private IWmUserService iWmUserService;

    @Override
    public ResponseResult findListByCondition(WmNewsPageDto dto) {
        //获取用户
        User user = WeMediaThreadLocal.get();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        LambdaQueryWrapper<WmNews> query = new LambdaQueryWrapper<>();
        query.eq(WmNews::getUserId, user.getUserId());
        //判断类型
        if (dto.getStatus() != null) {
            query.eq(WmNews::getStatus, dto.getStatus());
        }
        //判断时间
        if (dto.getBeginPubDate() != null) {
            query.gt(WmNews::getPublishTime, dto.getBeginPubDate());
        }
        if (dto.getEndPubDate() != null) {
            query.lt(WmNews::getPublishTime, dto.getEndPubDate());
        }
        //判断频道
        if (dto.getChannelId() != null) {
            query.eq(WmNews::getChannelId, dto.getChannelId());
        }
        //判断关键字
        if (dto.getKeyword() != null) {
            query.like(WmNews::getTitle, dto.getKeyword());
        }
        IPage<WmNews> page = new Page<>(dto.getPage(), dto.getSize());
        query.orderByDesc(WmNews::getCreatedTime);
        IPage<WmNews> iPage = this.page(page, query);
        return new PageResponseResult(dto.getPage(), dto.getSize(), iPage.getTotal(), iPage.getRecords());
    }

    @Override
    public ResponseResult submit(WmNewsDto dto) {
        //获取用户
        User user = WeMediaThreadLocal.get();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //判断是保存还是修改
        if (dto.getId() != null) {
            LambdaQueryWrapper<WmNews> query = new LambdaQueryWrapper<>();
            query.eq(WmNews::getUserId, user.getUserId());
        }
        //无图
        WmNews wmNews = new WmNews();
        //拷贝属性
        BeanUtils.copyProperties(dto, wmNews);
        wmNews.setUserId(user.getUserId());
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());
        //封面有图
        String imageStr = getImageStr(dto.getImages());
        wmNews.setImages(imageStr);
        //从文章中获取图片
        List<String> imageList = getImageFromContent(dto.getContent());
        if (dto.getType() == -1) {
            if (imageList.size() <= 0) {
                //无图
                wmNews.setType(0);
            } else if (imageList.size() <= 2) {
                wmNews.setType(1);
                wmNews.setImages(imageList.get(0));
            } else {
                wmNews.setType(3);
                List<String> list = imageList.subList(0, 3);
                String image = getImageStr(list);
                wmNews.setImages(image);
            }
        }
        //判断是否是草稿
        if (dto.getStatus() == 0) {
            this.saveOrUpdate(wmNews);
            return ResponseResult.okResult();
        }
        wmNews.setPublishTime(dto.getPublishTime());
        this.saveOrUpdate(wmNews);
        //从内容获取的图片于文章关联
        if (StringUtils.isNotEmpty(wmNews.getImages())){
            saveNewMaterial(wmNews, imageList, 0);
            //封面图片建立文章关联
            String[] images = wmNews.getImages().split(",");
            List<String> list = Arrays.asList(images);
            saveNewMaterial(wmNews, list, 1);
        }

        //发送到Kafka
        kafkaTemplate.send(autoAuditTopic,wmNews.getId().toString());

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteNews(Integer id) {
        //获取用户
        User user = WeMediaThreadLocal.get();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        WmNews wmNews = this.getById(id);
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if (!wmNews.getUserId().equals(user.getUserId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        if (wmNews.getStatus() == 9 && wmNews.getEnable()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEWS_CAN_NOT_DELETE);
        }
        this.removeById(id);
        LambdaQueryWrapper<WmNewsMaterial> query = new LambdaQueryWrapper<>();
        query.eq(WmNewsMaterial::getNewsId, wmNews.getId());
        iWmNewsMaterialService.remove(query);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult upOrDown(WmNewsDto dto) {
        //获取用户
        User user = WeMediaThreadLocal.get();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        WmNews wmNews = this.getById(dto.getId());
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if (wmNews.getStatus() != 9 || !wmNews.getUserId().equals(user.getUserId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        wmNews.setEnable(dto.getEnable() == 1 ? true : false);
        this.updateById(wmNews);

        Map<String,Object> map = new HashMap<>();
        map.put("id",wmNews.getArticleId());
        map.put("isDown",!wmNews.getEnable());
        kafkaTemplate.send(upDownTopic,JSON.toJSONString(map));
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<List<Integer>> getRelease() {
        LambdaQueryWrapper<WmNews> query = new LambdaQueryWrapper<>();
        query.in(WmNews::getStatus,4,8);
        query.lt(WmNews::getPublishTime,new Date());
        query.select(WmNews::getId);
        List<Integer> list = this.listObjs(query,x ->(Integer)x);
        return ResponseResult.okResult(list);
    }

    @Override
    public PageResponseResult findPageByName(NewsAuthDto dto) {
        LambdaQueryWrapper<WmNews> query = new LambdaQueryWrapper<>();
        if (dto.getTitle()!=null){
            query.like(WmNews::getTitle,dto.getTitle());
        }
        if (dto.getStatus()!=null){
            query.eq(WmNews::getStatus,dto.getStatus());
        }
        query.orderByDesc(WmNews::getPublishTime);
        IPage<WmNews> page = new Page<>(dto.getPage(),dto.getSize());
        IPage<WmNews> iPage = this.page(page, query);

        List<WmNews> newsList = iPage.getRecords();
        List<WmNewsVo> wmNewsVoList = new ArrayList<>();
        if (newsList!=null){
            for (WmNews wmNews : newsList) {
                WmUser wmUser = iWmUserService.getById(wmNews.getUserId());

                WmNewsVo wmNewsVo = new WmNewsVo();
                BeanUtils.copyProperties(wmNews,wmNewsVo);
                wmNewsVo.setAuthorName(wmUser.getName());

                wmNewsVoList.add(wmNewsVo);
            }
        }
        return new PageResponseResult(dto.getPage(),dto.getSize(),iPage.getTotal(),wmNewsVoList);
    }

    @Override
    public ResponseResult<WmNewsVo> findNewsVoById(Integer id) {
        WmNews wmNews = this.getById(id);
        WmNewsVo wmNewsVo = new WmNewsVo();
        WmUser wmUser = iWmUserService.getById(wmNews.getUserId());
        BeanUtils.copyProperties(wmNews,wmNewsVo);
        wmNewsVo.setAuthorName(wmUser.getName());
        return ResponseResult.okResult(wmNewsVo);
    }

    private void saveNewMaterial(WmNews wmNews, List<String> imageList, int type) {
        int ord = 0;
        for (String image : imageList) {
            LambdaQueryWrapper<WmMaterial> query = new LambdaQueryWrapper<>();
            query.eq(WmMaterial::getUrl, image);
            WmMaterial material = iWmMaterialService.getOne(query);
            if (material != null) {
                WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
                wmNewsMaterial.setMaterialId(material.getId());
                wmNewsMaterial.setNewsId(wmNews.getId());
                wmNewsMaterial.setType(type);
                wmNewsMaterial.setOrd(ord);
                iWmNewsMaterialService.save(wmNewsMaterial);
                ord++;
            }
        }
    }

    private List<String> getImageFromContent(String content) {
        List<String> list = new ArrayList<>();
        if (StringUtils.isNotEmpty(content)) {
            List<ContentDto> contentDtos = JSON.parseArray(content, ContentDto.class);
            for (ContentDto contentDto : contentDtos) {
                if (contentDto.getType().equals("image")) {
                    list.add(contentDto.getValue());
                }
            }
        }
        return list;
    }

    private String getImageStr(List<String> images) {
        List<String> list = new ArrayList<>();
        if (images.size() > 0) {
            String image = String.join(",", images);
            return image;
        }
        return null;
    }
}
